home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Talking Clock Pro™ 2.0b2 / Talking Clock Pro Source / Controller / Source / clockrec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-04  |  11.0 KB  |  466 lines  |  [TEXT/KAHL]

  1. /*
  2.  * clockrec.c
  3.  */
  4.  
  5. #include <AERegistry.h>
  6. #include <AEObjects.h>
  7.  
  8. #include <PlotIconSuite.h>
  9. #include "TalkConstants.h"
  10.  
  11. #include "apprec.h"
  12. #include "clockrec.h"
  13. #include "x.h"
  14. #include "menu.h"
  15. #include "window.h"
  16. #include "util.h"
  17. #include "str.h"
  18.  
  19.  
  20. #define DAEMON_TYPE 'appe'
  21.  
  22. Boolean hasController ;
  23.  
  24. DefWindowRec clockRec = {
  25.  
  26.     128 , NULL ,
  27.  
  28.     ClockCr ,
  29.     ClockDe ,
  30.     ClockUp ,
  31.     ClockMD ,
  32.     ClockMU ,
  33.     ClockKD ,
  34.     ClockAK ,
  35.     ClockAc ,
  36.     ClockSw ,
  37.     ClockId ,
  38.     ClockPr ,
  39.     ClockCo ,
  40.     ClockAE
  41.  
  42. } ;
  43.  
  44.  
  45. typedef struct ClockRec {
  46.     ProcessSerialNumber    psn ; /* The extension's process */
  47.     short                turnaround ;
  48.     Boolean                optionKeyTalk ;
  49.     Boolean                controlKeyTalk ;
  50.     Boolean                commandKeyTalk ;
  51.     Boolean                shiftKeyTalk ;
  52.     Boolean                capsLockKeyTalk ;
  53.     Boolean                fiveMinuteTalk ;
  54. } ClockRec , * ClockPtr ;
  55.  
  56.  
  57. typedef struct Switch {
  58.     short                xPos ;
  59.     short                yPos ;
  60.     short                xSize ;
  61.     short                ySize ;
  62.     short                nameIndex ;
  63.     OSType                prop ;
  64. } Switch , * SwitchPtr ;
  65.  
  66.  
  67. SwitchPtr switches = NULL ;
  68. int NUM_SWITCHES = 0 ;
  69.  
  70.  
  71.  
  72. static void
  73. ReadSwitches ( void ) {
  74.  
  75. Handle h ;
  76. int ix ;
  77.  
  78.     NUM_SWITCHES = Count1Resources ( 'SWTC' ) ;
  79.     switches = ( SwitchPtr ) NewPtrClear ( sizeof ( Switch ) * NUM_SWITCHES ) ;
  80.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  81.         h = Get1IndResource ( 'SWTC' , ix + 1 ) ;
  82.         HLock ( h ) ;
  83.         BlockMove ( * h , switches + ix , sizeof ( Switch ) ) ;
  84.         ReleaseResource ( h ) ;
  85.     }
  86. }
  87.  
  88.  
  89. static void
  90. DrawSwitch ( SwitchPtr sw , Boolean b ) {
  91.  
  92. Rect r ;
  93. Str63 name ;
  94.  
  95.     PenNormal ( ) ;
  96.     TextFont ( GetAppFont ( ) ) ;
  97.     TextSize ( sw -> ySize ) ;
  98.     SetRect ( & r , sw -> xPos , sw -> yPos , sw -> xPos + sw -> ySize ,
  99.         sw -> yPos + sw -> ySize ) ;
  100.     FrameRect ( & r ) ;
  101.     if ( b ) {
  102.         MoveTo ( r . left , r . top ) ;
  103.         Line ( sw -> ySize - 1 , sw -> ySize - 1 ) ;
  104.         MoveTo ( r . left , r . bottom - 1 ) ;
  105.         Line ( sw -> ySize - 1 , 1 - sw -> ySize ) ;
  106.     }
  107.     MoveTo ( sw -> xPos + 2 * sw -> ySize , sw -> yPos + sw -> ySize * 4 / 5 + 1 ) ;
  108.     GetIndString ( name , 132 , sw -> nameIndex ) ;
  109.     DrawString ( name ) ;
  110. }
  111.  
  112.  
  113. static Boolean
  114. TrackSwitch ( SwitchPtr sp ) {
  115.  
  116. Rect r , box ;
  117. Boolean in = 0 ;
  118. Boolean toIn = 1 ;
  119. Point p ;
  120.  
  121.     SetRect ( & r , sp -> xPos , sp -> yPos , sp -> xPos + sp -> xSize ,
  122.         sp -> yPos + sp -> ySize ) ;
  123.     box = r ;
  124.     box . right = box . left + sp -> ySize ;
  125.     InsetRect ( & box , 1 , 1 ) ;
  126.     PenMode ( patXor ) ;
  127.     while ( StillDown ( ) ) {
  128.         GetMouse ( & p ) ;
  129.         toIn = PtInRect ( p , & r ) ;
  130.         if ( toIn != in ) {
  131.             FrameRect ( & box ) ;
  132.             in = toIn ;
  133.         }
  134.     }
  135.     if ( in ) {
  136.         FrameRect ( & box ) ;
  137.     }
  138.     PenNormal ( ) ;
  139.  
  140.     return in ;
  141. }
  142.  
  143.  
  144. Boolean
  145. FindPSN ( OSType type , OSType creator , ProcessSerialNumber * psn ) {
  146.  
  147. ProcessInfoRec prInfo ;
  148.  
  149.     psn -> highLongOfPSN = 0 ;
  150.     psn -> lowLongOfPSN = kNoProcess ;
  151.     while ( ! GetNextProcess ( psn ) ) {
  152.         prInfo . processInfoLength = sizeof ( ProcessInfoRec ) ;
  153.         prInfo . processName = NULL ;
  154.         prInfo . processAppSpec = NULL ;
  155.         FailErr ( GetProcessInformation ( psn , & prInfo ) ) ;
  156.         if ( prInfo . processType == type &&
  157.             prInfo . processSignature == creator ) {
  158.             return 1 ;
  159.         }
  160.     }
  161.     return 0 ;
  162. }
  163.  
  164.  
  165. static Boolean
  166. GetRecData ( ClockPtr ptr , DescType theKey ) {
  167.  
  168. AEDesc aed ;
  169. AERecord rec ;
  170. AppleEvent aevt ;
  171. AppleEvent reply = { 0 , 0 } ;
  172. DescType type ;
  173. Boolean b ;
  174. long theSize ;
  175.  
  176.     FailErr ( AECreateDesc ( typeProcessSerialNumber , ( Ptr ) & ( ptr -> psn ) ,
  177.         sizeof ( ProcessSerialNumber ) , & aed ) ) ;
  178.     FailErr ( AECreateAppleEvent ( kAECoreSuite , kAEGetData , & aed ,
  179.         kAutoGenerateReturnID , kAnyTransactionID , & aevt ) ) ;
  180.     FailErr ( AEDisposeDesc ( & aed ) ) ;
  181.     FailErr ( AECreateList ( NULL , 0L , 1 , & rec ) ) ;
  182.     type = cProperty ;
  183.     FailErr ( AEPutKeyPtr ( & rec , keyAEDesiredClass , typeType ,
  184.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  185.     type = theKey ;
  186.     FailErr ( AEPutKeyPtr ( & rec , keyAEKeyData , typeType ,
  187.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  188.     FailErr ( AEPutParamDesc ( & aevt , keyDirectObject , & rec ) ) ;
  189.     FailErr ( AEDisposeDesc ( & rec ) ) ;
  190.     type = typeBoolean ;
  191.     FailErr ( AEPutParamPtr ( & aevt , keyAERequestedType , typeType ,
  192.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  193.     FailErr ( AESend ( & aevt , & reply , kAEWaitReply , kAEHighPriority ,
  194.         20L , NULL , NULL ) ) ;
  195.     FailErr ( AEDisposeDesc ( & aevt ) ) ;
  196.     FailErr ( AEGetParamPtr ( & reply , keyAEResult , typeBoolean , & type ,
  197.         ( Ptr ) & b , sizeof ( b ) , & theSize ) ) ;
  198.     FailErr ( AEDisposeDesc ( & reply ) ) ;
  199.  
  200.     return b ;
  201. }
  202.  
  203.  
  204. static void
  205. SetRecData ( ClockPtr ptr , DescType theKey , Boolean b ) {
  206.  
  207. AEDesc aed = { 0 , 0 } ;
  208. AERecord rec = { 0 , 0 } ;
  209. AppleEvent aevt = { 0 , 0 } ;
  210. AppleEvent reply = { 0 , 0 } ;
  211. DescType type ;
  212.  
  213.     TRY {
  214.         FailErr ( AECreateDesc ( typeProcessSerialNumber , ( Ptr ) & ( ptr -> psn ) ,
  215.             sizeof ( ProcessSerialNumber ) , & aed ) ) ;
  216.         FailErr ( AECreateAppleEvent ( kAECoreSuite , kAESetData , & aed ,
  217.             kAutoGenerateReturnID , kAnyTransactionID , & aevt ) ) ;
  218.         FailErr ( AECreateList ( NULL , 0L , 1 , & rec ) ) ;
  219.         type = cProperty ;
  220.         FailErr ( AEPutKeyPtr ( & rec , keyAEDesiredClass , typeType ,
  221.             ( Ptr ) & type , sizeof ( type ) ) ) ;
  222.         type = theKey ;
  223.         FailErr ( AEPutKeyPtr ( & rec , keyAEKeyData , typeType ,
  224.             ( Ptr ) & type , sizeof ( type ) ) ) ;
  225.         FailErr ( AEPutParamDesc ( & aevt , keyDirectObject , & rec ) ) ;
  226.         FailErr ( AEPutParamPtr ( & aevt , keyAEData , typeBoolean ,
  227.             ( Ptr ) & b , sizeof ( b ) ) ) ;
  228.         FailErr ( AESend ( & aevt , & reply , kAENoReply , kAEHighPriority ,
  229.             20L , NULL , NULL ) ) ;
  230.     } CLEANUP {
  231.         FailErr ( AEDisposeDesc ( & rec ) ) ;
  232.         FailErr ( AEDisposeDesc ( & aed ) ) ;
  233.         FailErr ( AEDisposeDesc ( & aevt ) ) ;
  234.         FailErr ( AEDisposeDesc ( & reply ) ) ;
  235.         if ( __err == errAETimeout ) {
  236.             NO_PROPAGATE ;
  237.         }
  238.     } DONE ;
  239. }
  240.  
  241.  
  242. static void
  243. FillRec ( ClockPtr ptr ) {
  244.  
  245.     ptr -> optionKeyTalk = GetRecData ( ptr , pOptionKeyTalk ) ;
  246.     ptr -> commandKeyTalk = GetRecData ( ptr , pCommandKeyTalk ) ;
  247.     ptr -> controlKeyTalk = GetRecData ( ptr , pControlKeyTalk ) ;
  248.     ptr -> shiftKeyTalk = GetRecData ( ptr , pShiftKeyTalk ) ;
  249.     ptr -> capsLockKeyTalk = GetRecData ( ptr , pCapsLockKeyTalk ) ;
  250.     ptr -> fiveMinuteTalk = GetRecData ( ptr , pFiveMinuteTalk ) ;
  251. }
  252.  
  253.  
  254. static void
  255. SetRec ( ClockPtr ptr ) {
  256.  
  257.     SetRecData ( ptr , pOptionKeyTalk , ptr -> optionKeyTalk ) ;
  258.     SetRecData ( ptr , pCommandKeyTalk , ptr -> commandKeyTalk ) ;
  259.     SetRecData ( ptr , pControlKeyTalk , ptr -> controlKeyTalk ) ;
  260.     SetRecData ( ptr , pShiftKeyTalk , ptr -> shiftKeyTalk ) ;
  261.     SetRecData ( ptr , pCapsLockKeyTalk , ptr -> capsLockKeyTalk ) ;
  262.     SetRecData ( ptr , pFiveMinuteTalk , ptr -> fiveMinuteTalk ) ;
  263. }
  264.  
  265.  
  266. /*    A window is being created or opened. Allocate data and        */
  267. /*    select the window                                    */
  268. OSErr
  269. ClockCr ( WindowPtr wp , Handle * data , FSSpec * file ) {
  270.  
  271. ClockPtr ptr ;
  272.  
  273.     if ( ! NUM_SWITCHES ) {
  274.         ReadSwitches ( ) ;
  275.     }
  276.     * data = NewHandle ( sizeof ( ClockRec ) ) ;
  277.     FailNil ( * data ) ;
  278.     HLockHi ( * data ) ;
  279.     ptr = ( ClockPtr ) * * data ;
  280.     if ( ! FindPSN ( DAEMON_TYPE , 'O\'Cl' , & ( ptr -> psn ) ) ) {
  281.         Alert ( 130 , NULL ) ;
  282.         hasController = 0 ;
  283.         return 1 ;
  284.     } else {
  285.         FillRec ( ptr ) ;
  286.         hasController = 1 ;
  287.     }
  288.     return noErr ;
  289. }
  290.  
  291.  
  292. /*    Window is being destroyed. Put up a warning dialog, and        */
  293. /*    return errCancel if the user cancels closing - else call    */
  294. /*    DisposeWindow here                                            */
  295. OSErr
  296. ClockDe ( WindowPtr wp , Handle data ) {
  297.  
  298. ProcessSerialNumber psn ;
  299.  
  300.     if ( hasController ) {
  301.         SetRec ( ( ClockPtr ) * data ) ;
  302.         hasController = 0 ;
  303.         if ( FindPSN ( 'FNDR' , 'MACS' , & psn ) ) {
  304.             FailErr ( SetFrontProcess ( & psn ) ) ;
  305.         }
  306.     }
  307.     DisposeHandle ( data ) ;
  308.     DisposeWindow ( wp ) ;
  309.     return noErr ;
  310. }
  311.  
  312.  
  313. /*    Update the window - BeginUpdate is already called            */
  314. OSErr
  315. ClockUp ( WindowPtr wp , Handle data , EventRecord * event ) {
  316.  
  317. short ix ;
  318. Handle h ;
  319. ClockPtr ptr = ( ClockPtr ) * data ;
  320. Rect r = { 10 , 10 , 42 , 42 } ;
  321. Str255 s ;
  322.  
  323.     FailErr ( GetIconSuite ( & h , 128 , -1L ) ) ;
  324.     EraseRect ( & ( wp -> portRect ) ) ;
  325.     FailErr ( PlotIconSuite ( & r , atNone , ttNone , h ) ) ;
  326.     FailErr ( DisposeIconSuite ( h , FALSE ) ) ;
  327.  
  328.     TextFont ( GetAppFont ( ) ) ;
  329.     TextSize ( GetDefFontSize ( ) ) ;
  330.  
  331.     SetRect ( & r , 52 , 10 , wp -> portRect . right - 8 , 40 ) ;
  332.     GetIndString ( s , 131 , 1 ) ;
  333.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  334.  
  335.     TextSize ( GetDefFontSize ( ) * 4 / 5 ) ;
  336.  
  337.     SetRect ( & r , 10 , 52 , wp -> portRect . right - 8 , 80 ) ;
  338.     GetIndString ( s , 131 , 2 ) ;
  339.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  340.  
  341.     SetRect ( & r , 10 , wp -> portRect . bottom - 35 ,
  342.         wp -> portRect . right - 8 , wp -> portRect . bottom ) ;
  343.     GetIndString ( s , 131 , 3 ) ;
  344.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  345.  
  346.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  347.         DrawSwitch ( & switches [ ix ] , !! ( & ( ptr -> optionKeyTalk ) ) [ ix ] ) ;
  348.     }
  349.     return noErr ;
  350. }
  351.  
  352.  
  353. /*    The user clicked in your window. The window port is set and    */
  354. /*    event -> where is translated into local coordinates now        */
  355. OSErr
  356. ClockMD ( WindowPtr wp , Handle data , EventRecord * event ) {
  357.  
  358. short ix ;
  359. Rect r ;
  360. SwitchPtr sp = switches ;
  361. ClockPtr ptr = ( ClockPtr ) * data ;
  362.  
  363.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  364.         SetRect ( & r , sp -> xPos , sp -> yPos , sp -> xPos + sp -> xSize ,
  365.             sp -> yPos + sp -> ySize ) ;
  366.         if ( PtInRect ( event -> where , & r ) ) {
  367.             break ;
  368.         }
  369.         sp ++ ;
  370.     }
  371.     if ( ix < NUM_SWITCHES ) {
  372.         if ( TrackSwitch ( sp ) ) {
  373.             ( & ( ptr -> optionKeyTalk ) ) [ ix ] = ! ( & ( ptr -> optionKeyTalk ) ) [ ix ] ;
  374.             SetPort ( wp ) ;
  375.             InvalRect ( & r ) ;
  376.         }
  377.     }
  378.     return noErr ;
  379. }
  380.  
  381.  
  382. /*    MouseUp in a window - you probably should do nothing        */
  383. OSErr
  384. ClockMU ( WindowPtr wp , Handle data , EventRecord * event ) {
  385.  
  386.     return noErr ;
  387. }
  388.  
  389.  
  390. /*    The user typed in the window - command keys are already        */
  391. /*    taken care of and don't come here                            */
  392. OSErr
  393. ClockKD ( WindowPtr wp , Handle data , EventRecord * event ) {
  394.  
  395.     return noErr ;
  396. }
  397.  
  398.  
  399. /*    You probably just want to call the KeyDown handler here        */
  400. OSErr
  401. ClockAK ( WindowPtr wp , Handle data , EventRecord * event ) {
  402.  
  403.     return noErr ;
  404. }
  405.  
  406.  
  407. /*    Activate event - highlight/dehighlight controls & caret        */
  408. OSErr
  409. ClockAc ( WindowPtr wp , Handle data , EventRecord * event ) {
  410.  
  411.     return noErr ;
  412. }
  413.  
  414.  
  415. /*    You should probably build a suitable activate event and        */
  416. /*    send to the activate handling for MultiFinder switches        */
  417. OSErr
  418. ClockSw ( WindowPtr wp , Handle data , EventRecord * event ) {
  419.  
  420.     return noErr ;
  421. }
  422.  
  423.  
  424. /*    Idle time - set the sleep parameter if it's too large for    */
  425. /*    your needs. GetCaretTime() is a good value for text editors    */
  426. OSErr
  427. ClockId ( WindowPtr wp , Handle data , long * sleep ) {
  428.  
  429.     return AppId ( wp , app . data , sleep ) ;
  430. }
  431.  
  432.  
  433. /*    This is called when menus need to be updated.                */
  434. OSErr
  435. ClockPr ( WindowPtr wp , Handle data ) {
  436.  
  437.     FailErr ( AppPr ( wp , app . data ) ) ;
  438.     EnableCmd ( FILE_MENU , CLOSE_ITEM ) ;
  439.     return noErr ;
  440. }
  441.  
  442.  
  443. /*    A menu selection was made - take appropriate action            */
  444. OSErr
  445. ClockCo ( WindowPtr wp , Handle data , short menu , short item ,
  446.     unsigned char * itemStr ) {
  447.  
  448.     if ( menu == FILE_MENU && item == CLOSE_ITEM ) {
  449.         DestroyWindow ( wp ) ;
  450.     } else {
  451.         FailErr ( AppCo ( wp , app . data , menu , item , itemStr ) ) ;
  452.     }
  453.  
  454.     return noErr ;
  455. }
  456.  
  457.  
  458. /*    An AppleEvent was received with this window in front        */
  459. OSErr
  460. ClockAE ( WindowPtr wp , Handle data , AppleEvent * event ,
  461.     AppleEvent * reply ) {
  462.  
  463.     return noErr ;
  464. }
  465.  
  466.